use rand::Rng;
use std::cmp::Ordering;
use std::io;

const TST: u32 = 12;
fn main() {
    // 堆上的数据采用clone方法进行实现
    // let mut ch = String::from("hello world");
    // ch.push_str(" world");
    // let ch1 = ch.clone();
    // let x = 12;
    // let re = test_one(x, ch, 3.0);
    // // 此处ch报错，因为它的所有权被test_one的入参持有
    // println!("re = {re}, ch1 = {ch1}");
    // println!("x is {}", x);

    // test_calculate_length();
    let ch = String::from("hello world");
    reference_calculate_length(&ch);

    let mut ch1 = String::from("hello world");
    mut_reference_calculate_length(&mut ch1);
    mut_reference_calculate_length1(&mut ch1);

    let t = &mut ch1;
    let t2 = &mut *t;

    println!("{}, {}", t2, t2);
    println!("{}", ch1);

    test_mut();
    // 接受被释放的引用内容
    // let reference_to_nothing = dangle();

    let mut s = String::from("hello world");

    let word = first_word(&s);

    println!("the first word is: {word}");

    s.clear(); // 错误！
}

fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }

    &s[..]
}

// fn dangle() -> &String {
//     let s = String::from("hello");
//
//     // 返回s的引用，s按着所有权规则在}以后会被释放
//     &s
// }

fn test_mut() {
    let mut s = String::from("hello");

    let r1 = &s; // 没问题
    let r2 = &s; // 没问题
    println!("{r1} and {r2}");
    // 此位置之后 r1 和 r2 不再使用

    let r3 = &mut s; // 没问题

    // 当不可变引用还没用完前拥有可变引用是不允许的
    // println!("{r1} and {r2}");

    println!("{r3}");
}

fn mut_reference_calculate_length1(s: &mut String) -> usize {
    println!("{}", s.len());
    s.len()
}
fn mut_reference_calculate_length(s: &mut String) -> usize {
    s.len()
}

fn reference_calculate_length(s: &String) -> usize {
    s.len()
}
fn test_calculate_length() {
    let s1 = String::from("hello");

    // s1的所有权传入calculate_length中，元组返回s1的所有权并解构成s2。此处也可以使用s1进行接收。
    let (s1, len) = calculate_length(s1);

    println!("The length of '{s1}' is {len}.");
}
fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len() 返回字符串的长度

    (s, length)
}

fn day_01() {
    println!("Guess the number!{}", TST);

    let secret_number = rand::thread_rng().gen_range(1..=100);

    println!("The secret number is: {secret_number}");

    let _age_t = 1;
    let _age_t = 2;
    let _age_t = 3;
    println!("current age {}", _age_t);

    let tup: (f32, u32, bool) = (3.1, 3, false);
    let (x, y, z) = tup;
    let mut de: f32 = tup.0;
    println!("x: {}, y: {}, z: {},tup:{}", x, y, z, de);
    de = 12.1;
    println!("x: {}, y: {}, z: {},tup:{}", x, y, z, de);

    let tup1: () = ();
    println!("{:?}", tup1);

    let array: [i32; 5] = [1, 2, 3, 4, 5];
    let a_one = array[0];
    println!("The value of a_one is: {}", a_one);
    println!("{:?}", array);

    let two_d_array: [[i32; 3]; 3] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
    println!("{:?}", two_d_array);

    loop {
        println!("Please input your guess.");

        let mut guess: String = String::new();

        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read line");

        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => continue,
        };

        println!("You guessed: {guess}");

        match guess.cmp(&secret_number) {
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too big!"),
            Ordering::Equal => {
                println!("You win!");
                break;
            }
        }
    }
}

fn test_one(mut x: i32, sd: String, f: f32) -> String {
    x = x + 1;
    println!("The value of x is: {}", x);
    println!("The value of str is: {}", sd);
    println!("The value of f is: {}", f);
    String::from("hello world")
}

fn test_two() {
    let y = {
        let x = 3;
        x + 1
    };

    println!("The value of y is: {y}");
}

/// 这是一个返回样例
/// # Examples
/// ```
/// test_three(12);
/// ```
/// 这里的return可以省略
fn test_three(x: i32) -> i32 {
    return x + 1;
}

fn test_if() {
    let number = 3;
    if number < 5 {
        println!("condition was true");
    } else if number > 5 {
        println!("condition was false");
    } else {
        println!("condition was false");
    }

    let number2 = if number == 3 { 4 } else { 12 };

    let x = 5;
    let y = 3;
    let result: &str = if x > y {
        "x is greater than y"
    } else {
        "x is not greater than y"
    };
    println!("result->{}", result);
}

fn test_loop() {
    let mut counter = 0;

    let result: i32 = loop {
        counter += 1;

        if counter == 10 {
            break counter * 2;
        }
    };

    println!("The result is {result}");
}

fn test_for() {
    for i in 0..10 {
        println!("{i}");
    }
    println!("LIFTOFF!!!");
}

fn test_ownership() {
    let mut st = String::from("hello");
    // 当st赋值给s2后,st将不再有效。
    let s2 = st;

    println!("The value of s2 is: {}", s2);
    // st.push_str("12");
    println!("The value of s2 is: {}", s2);
    // println!("The value of s2 is: {}", st);
}
